import math
import copy
import numpy as np
from util import *
from Method.OurMethod import OurMethod
from Method.OurMethod_slight import OurMethod_slight
from Method.GSMS import GSMS
from Method.HEFT import HEFT
from Method.DRR import DRR
from Method.RR import RR
from Method.R_RIR import R_RIR
from Method.QFEC import QFEC
from Method.C_GM import C_GM
class Scheduler:
    def __init__(self,cloud_system):
        self.cloud_system=cloud_system
        self.env=cloud_system.env
        self.print_level=cloud_system.print_level
        self.deploy_schedule_strategy=cloud_system.args.deploy_schedule_strategy
        self.delay_schedule_flage=False
        self.last_schedule_time=-1
        #初始化
        if self.cloud_system.args.deploy_schedule_strategy=="ours":
            # self.method=OurMethod_slight(self.cloud_system)
            self.method=OurMethod(self.cloud_system)
            if self.cloud_system.args.pre_deploy==False or self.cloud_system.args.dynamic_replica==False:
                temp=GSMS(self.cloud_system)
                self.method.base_method=temp
                
            
        elif self.cloud_system.args.deploy_schedule_strategy=="GSMS":
            self.method=GSMS(self.cloud_system)
        elif self.cloud_system.args.deploy_schedule_strategy=="HEFT":
             self.method=HEFT(self.cloud_system)
        elif self.cloud_system.args.deploy_schedule_strategy=="DRR":
            self.method=DRR(self.cloud_system)
        elif self.cloud_system.args.deploy_schedule_strategy=="RR":
            self.method=RR(self.cloud_system)
        elif self.cloud_system.args.deploy_schedule_strategy=="R_RIR":
            self.method=R_RIR(self.cloud_system)
        elif self.cloud_system.args.deploy_schedule_strategy=="QFEC":
            self.method=QFEC(self.cloud_system)
        elif self.cloud_system.args.deploy_schedule_strategy=="C_GM":
            self.method=C_GM(self.cloud_system)
        else:
            print(f"method name wrong! (should be ours, GSMS)")
        return

    def init_deploy(self):
        self.method.init_deploy()
        return
        
        
    def do_schedule_deploy(self):
        
        #提前剔除已经存在超时的task的请求中的task
        # for task in self.cloud_system.pending_task_queue:
        #     if task.request.task_response_timeout_flage:
        #         self.cloud_system.pending_task_queue.remove(task)
        
        #如果等待任务队列存在元素，则进行调度
        if len(self.cloud_system.pending_task_queue)>0 and self.last_schedule_time!=self.env.now: 
            if self.cloud_system.print_level>10:
                print(f"Time:{round(self.env.now)}\t (STA SCHE EVENT)\tqueue length:{len(self.cloud_system.pending_task_queue)}")
                     
            self.method.do_schedule_deploy() 
            self.last_schedule_time=self.env.now 
            if self.cloud_system.print_level>10:
                print(f"Time:{round(self.env.now)}\t (END SCHE EVENT)\tqueue length:{len(self.cloud_system.pending_task_queue)}")   
           
        # if len(self.cloud_system.pending_task_queue)>0 and self.delay_schedule_flage==False:
        #     self.delay_schedule_flage=True
        #     self.cloud_system.env.process(self.__delay_deploy_schedule(10))
            
        return
    
    def do_schedule_deploy_event(self):
        yield self.cloud_system.env.timeout(0)
        self.do_schedule_deploy()
    # def __delay_deploy_schedule(self, delay):
    #     yield self.cloud_system.env.timeout(delay)
    #     self.do_schedule_deploy()
    #     self.delay_schedule_flage=False
            
    def ms_complete_and_can_be_rm(self,ms_obj):
        if self.cloud_system.args.elastic_deploy==True:
            self.method.ms_complete_and_can_be_rm(ms_obj)
            
            
    # def deploy_ours(self, interval, each_ms_kind_deploy_number):
    #     self.cloud_system.env.process(self.our_method.deploy(interval, each_ms_kind_deploy_number))
        
    # def schedule_ours(self):
    #     self.our_method.schedule()
            

#################################################################################################################
    # def release_ms_id(self, request_id, ms_id):
    #     self.using_ms_id_dict[request_id].remove(ms_id)
        
    # def record_using_ms_id(self, request_id, ms_id):
    #     if request_id in self.using_ms_id_dict.keys():
    #         self.using_ms_id_dict[request_id].append(ms_id)
    #     else:
    #         self.using_ms_id_dict[request_id]=[ms_id]
    # def judge_ms_id_using(self, request_id, ms_id):
    #     if request_id in self.using_ms_id_dict.keys() and ms_id in self.using_ms_id_dict[request_id]:
    #         return True
    #     else:
    #         return False